<!-- canvas 生成表格，有合并表头 -->
<template>
    <div class="canvas-table">
        <div class="canvas-box">
            <canvas canvas-id="canvasId" class="canvas" />
            <el-icon color="#000" class="no-inherit canvas-close" @click="changeCloseCavvas">
                <Close />
            </el-icon>
        </div>
    </div>
</template>

<script setup lang='ts'>
import { ref } from 'vue';

const tableData = ref([]); // 表格数据

// 关闭
const changeCloseCavvas = () => {
    const canvas: any = document.querySelector(".canvas");
    const close: any = document.querySelector('.canvas-close');
    canvas.style.display = "none";
    close.style.display = "none";
}

// 生成表格
const changeReportforms = () => {
    const canvas: any = document.querySelector(".canvas");
    const close: any = document.querySelector('.canvas-close');
    close.classList.add('active-close');
    canvas.style.display = "block";
    close.style.display = "block";
    let ctx = canvas.getContext("2d");
    canvas.width = 1600;  // 设置画布宽度
    canvas.height = 800;

    let columnH = 40; // 表格每项的高
    let columnW = [90, 90, 80, 80, 90, 80, 110, 90, 90, 90, 90, 220, 160, 220]; // 表格每项的宽
    const paddingLeft = 20; // 设置左侧边距
    const paddingRight = 20; // 设置右侧边距
    canvas.style.border = "1px solid #ccc";

    // 设置背景颜色
    ctx.fillStyle = "green";
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // 绘制标题
    const titleHeight = 100; // 标题高度
    ctx.fillStyle = "#000"; // 标题文字颜色
    ctx.font = "30px Arial"; // 标题字体
    ctx.textAlign = "center"; // 居中对齐
    ctx.textBaseline = "middle"; // 垂直居中
    ctx.fillText("国防科技学院/核科学技术学院实验室安全日查记录册", canvas.width / 2, titleHeight / 2);

    // 设置表格起始位置
    const tableStartY = titleHeight + 10; // 表格起始 Y 坐标，10 是标题与表格的间距
    const tableWidth = canvas.width - paddingLeft - paddingRight; // 表格宽度
    const tableStartX = paddingLeft; // 表格起始 X 坐标，左侧有 paddingLeft

    // 设置线条样式
    ctx.strokeStyle = "#000"; // 网格线颜色
    ctx.lineWidth = 1; // 网格线宽度

    // 绘制表格横线
    for (let i = 0; i < tableData.value.length + 2; i++) {
        ctx.beginPath();
        ctx.moveTo(tableStartX, tableStartY + columnH * i);
        ctx.lineTo(tableStartX + tableWidth, tableStartY + columnH * i); // 结束点根据表格宽度调整
        ctx.stroke();
    }

    // 绘制表格竖线
    let currentX = tableStartX;
    for (let i = 0; i < 14; i++) {
        ctx.beginPath();
        ctx.moveTo(currentX, tableStartY);
        ctx.lineTo(currentX, tableStartY + columnH * (tableData.value.length + 1));
        ctx.stroke();
        currentX += columnW[i];
    }

    // 绘制右侧最后一列竖线
    currentX = tableStartX + tableWidth; // 右侧最后一列的位置
    ctx.beginPath();
    ctx.moveTo(currentX, tableStartY);
    ctx.lineTo(currentX, tableStartY + columnH * (tableData.value.length + 1));
    ctx.stroke();

    // 绘制表格文字
    currentX = tableStartX; // 重置 X 坐标
    ctx.fillStyle = "#ff0000"; // 表格文字颜色
    ctx.font = "14px Arial"; // 表格文字字体
    ctx.textBaseline = "top"; // 文字对齐方式
    // 第一行表头
    ctx.fillText("日期", currentX + 40, tableStartY + 15);
    currentX += columnW[0];
    ctx.fillText("值日生", currentX + 45, tableStartY + 15);
    currentX += columnW[1];
    ctx.fillText("卫生检查", currentX + 40, tableStartY + 15);
    currentX += columnW[2];
    ctx.fillText("水电检查", currentX + 40, tableStartY + 15);
    currentX += columnW[3];
    ctx.fillText("化学品检查", currentX + 45, tableStartY + 15);
    currentX += columnW[4];
    ctx.fillText("气瓶检查", currentX + 40, tableStartY + 15);
    currentX += columnW[5];
    ctx.fillText("加热设备检查", currentX + 55, tableStartY + 15);
    currentX += columnW[6];
    ctx.fillText("消防检查", currentX + 45, tableStartY + 15);
    currentX += columnW[7];
    ctx.fillText("是否申请", currentX + 45, tableStartY + 25);
    currentX += columnW[8];
    ctx.fillText("申请人", currentX + 40, tableStartY + 25);
    currentX += columnW[9];
    ctx.fillText("批准导师", currentX + 45, tableStartY + 25);
    currentX += columnW[10];
    ctx.fillText("最后离开人签名（门窗检查）", currentX + 115, tableStartY + 15);
    currentX += columnW[11];
    ctx.fillText("最后离开实验室时间", currentX + 80, tableStartY + 15);
    currentX += columnW[12];
    ctx.fillText("发现的安全问题及解决措施", currentX + 100, tableStartY + 15);
    currentX += columnW[13];

    tableData.value.forEach((rowData: any, rowIndex: number) => {
        currentX = tableStartX; // 重置 X 坐标
        let rowY = tableStartY + (rowIndex + 1) * columnH;

        const rowValues = [
            rowData.date, rowData.realName, rowData.doHealth, rowData.doWater, rowData.doChemicals,
            rowData.doBottle, rowData.dowaste, rowData.dofire, rowData.status,
            rowData.stayUser, rowData.teacherNo, rowData.lastLeave, rowData.leaveTime, rowData.solve
        ];

        rowValues.forEach((value, index) => {
            if (typeof value === 'number') {
                value = value == 0 ? 'x' : '√';
            }
            const map: any = {
                11: () => ctx.fillText(value, currentX + 100, rowY + 15),
                12: () => ctx.fillText(value, currentX + 80, rowY + 15),
                13: () => ctx.fillText(value, currentX + 110, rowY + 15),
            }

            if (index === 13) {
                const columnWidth = columnW[index];  // 获取当前列的宽度
                const maxHeight = 2; // 两行
                const lineHeight = 18; // 每行的行高
                const maxCharsPerLine = 13; // 每行最多10个字
                const wrappedLines: any = [];
                let currentLine = '';
                let text = value;

                while (text.length > 0) {
                    // 获取当前行的字符
                    let testLine = currentLine + text.charAt(0);

                    // 判断是否已达到最大字符数
                    if (currentLine.length < maxCharsPerLine) {
                        currentLine = testLine;
                        text = text.slice(1);
                    } else {
                        wrappedLines.push(currentLine);
                        currentLine = text.charAt(0);
                        text = text.slice(1);
                    }

                    if (wrappedLines.length >= maxHeight) {
                        break;
                    }
                }

                if (wrappedLines.length >= maxHeight) {
                    wrappedLines[wrappedLines.length - 1] = wrappedLines[wrappedLines.length - 1].slice(0, wrappedLines[wrappedLines.length - 1].length - 3) + '...';
                } else {
                    wrappedLines.push(currentLine);
                }

                // 绘制换行后的文字
                wrappedLines.forEach((line, lineIndex) => {
                    ctx.fillText(line, currentX + 105, rowY + lineIndex * lineHeight + (wrappedLines.length === 2 ? 6 : 15));
                });

            } else {
                Object.hasOwn(map, index) ? map[index]() : ctx.fillText(value, currentX + 45, rowY + 15);
            }
            currentX += columnW[index];
        });
    });

    // 合并表头的高度
    const mergedHeaderHeight = 20;

    // 计算坐标
    let mergeStartX = columnW[0] + columnW[1] + columnW[2] + columnW[3] + columnW[4] + columnW[5] + columnW[6]; // 距离x的坐标
    let mergeWidth = columnW[7] + columnW[8] + columnW[9]; // 宽度

    ctx.fillStyle = "green"; // 合并表头背景色
    ctx.fillRect(mergeStartX + 110, tableStartY, mergeWidth, mergedHeaderHeight);

    // 表头文字
    ctx.strokeStyle = "#000"; // 网格线颜色
    ctx.lineWidth = 1; // 网格线宽度
    ctx.strokeRect(mergeStartX + 110, tableStartY, mergeWidth, mergedHeaderHeight);

    ctx.fillStyle = "#ff0000"; // 文字颜色
    ctx.font = "14px Arial"; // 字体
    ctx.textAlign = "center"; // 居中对齐
    ctx.textBaseline = "middle"; // 垂直居中
    ctx.fillText("过夜实验申请", mergeStartX + 110 + mergeWidth / 2, tableStartY + mergedHeaderHeight / 2);

    const dataURL = canvas.toDataURL();

    console.log('dataURL', dataURL);
};
</script>


<style lang="scss" scoped>
.canvas-table {
    position: relative;

    .canvas {
        position: absolute;
        top: 0;
        z-index: 10;
    }

    .canvas-close {
        display: none;
    }

    .active-close {
        display: block;
        font-size: 30px;
        position: absolute;
        top: 0px;
        right: 20px;
        z-index: 100;
    }
}
</style>